package com.thinkgem.jeesite.modules.gen.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thinkgem.jeesite.common.persistence.BasePage;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.frame.pm.entity.PmDataDictItem;
import com.thinkgem.jeesite.frame.pm.utils.PmDataDictUtils;
import com.thinkgem.jeesite.modules.gen.core.GenFileBean;
import com.thinkgem.jeesite.modules.gen.entity.GenProject;
import com.thinkgem.jeesite.modules.gen.entity.GenProjectModule;
import com.thinkgem.jeesite.modules.gen.entity.GenScheme;
import com.thinkgem.jeesite.modules.gen.entity.GenTable;
import com.thinkgem.jeesite.modules.gen.service.*;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.Charsets;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 生成方案Controller
 *
 * @author kongxiangsheng
 * @version 2013-10-15
 */
@Controller
@RequestMapping(value = "${adminPath}/gen/genScheme")
@Slf4j
public class GenSchemeController extends BaseController {

    @Autowired
    private GenSchemeService genSchemeService;
    @Autowired
    private GenProjectService genProjectService;
    @Autowired
    private GenProjectModuleService genProjectModuleService;
    @Autowired
    private GenTemplateService genTemplateService;
    @Autowired
    private GenTableService genTableService;

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(value = {"list", ""})
    public String list(GenScheme genScheme, HttpServletRequest request, HttpServletResponse response, Model model) {
        BasePage<GenScheme> page = new BasePage<GenScheme>(request, response);
        genSchemeService.page(page, new QueryWrapper<GenScheme>(genScheme));

        model.addAttribute("page", page);
        return "modules/gen/GenScheme/list";
    }

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(value = "form")
    public String form(GenScheme genScheme, Model model) {
        if(StringUtils.isNotBlank(genScheme.getId())){
            genScheme = genSchemeService.getById(genScheme.getId());
        }
        model.addAttribute("genScheme", genScheme);
        model.addAttribute("templateList", genTemplateService.getAllTemplateDict());
        model.addAttribute("projectList", genProjectService.getAllProjectDict());
        model.addAttribute("tableList", genTableService.getAllTableDict());
        if(StringUtils.isBlank(genScheme.getAuthor())){
            genScheme.setAuthor(UserUtils.getUser().getLoginName());
        }

        // 导入导出
        PmDataDictItem pmImport = new PmDataDictItem();
        pmImport.setItemCode("import");
        pmImport.setItemName("导入");
        PmDataDictItem pmExport = new PmDataDictItem();
        pmExport.setItemCode("export");
        pmExport.setItemName("导出");
        List<PmDataDictItem> importExport = new ArrayList<PmDataDictItem>();
        importExport.add(pmImport);
        importExport.add(pmExport);
        model.addAttribute("importExport", importExport);

        return "modules/gen/GenScheme/form";
    }

    @RequiresPermissions("gen:genScheme:edit")
    @RequestMapping(value = "save")
    public String save(GenScheme genScheme, Model model, RedirectAttributes redirectAttributes, HttpServletResponse response) throws Exception {
        if (!beanValidator(model, genScheme)) {
            return form(genScheme, model);
        }

        // 保存
        genSchemeService.saveOrUpdate(genScheme);

        addMessage(redirectAttributes, "操作生成方案'" + genScheme.getName() + "'成功");
        return "redirect:" + adminPath + "/gen/genScheme/?repage";
    }

    @RequiresPermissions("gen:genScheme:edit")
    @RequestMapping(value = "downLoadZip")
    public void downLoadZip(GenScheme genScheme, HttpServletResponse response) throws Exception {
        // 生成代码
        List<GenFileBean> genFileList = genSchemeService.generate(genScheme);

        // 下载
        String downloadFileName = genScheme.getGenTable().getName();

        downThisFileList(response, genFileList, downloadFileName);
    }

    @RequiresPermissions("gen:genScheme:edit")
    @RequestMapping(value = "delete")
    public String delete(GenScheme genScheme, RedirectAttributes redirectAttributes) {
        genSchemeService.removeById(genScheme.getId());
        addMessage(redirectAttributes, "删除生成方案成功");
        return "redirect:" + adminPath + "/gen/genScheme/?repage";
    }

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(method = RequestMethod.GET, value = "ajaxGetProjectModules")
    @ResponseBody
    public List<GenProjectModule> ajaxGetProjectModules(String projectId) {
        List<GenProjectModule> moduleList = genProjectModuleService.getModulesDict(projectId);
        if(null == moduleList || moduleList.isEmpty()){
            GenProjectModule module = new GenProjectModule();
            module.setId("nothing");
            module.setModuleCode("无");
            moduleList.add(module);
        }
        return moduleList;
    }

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(method = RequestMethod.GET, value = "ajaxGetProjectBasePackage")
    @ResponseBody
    public String ajaxGetProjectBasePackage(String projectId) {
        return genProjectService.getProjectPackage(projectId);
    }

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(method = RequestMethod.GET, value = "ajaxGetModuleBasePackage")
    @ResponseBody
    public String ajaxGetModuleBasePackage(String moduleId) {
        return genProjectModuleService.getModulePackage(moduleId);
    }

    @RequiresPermissions("gen:genScheme:view")
    @RequestMapping(method = RequestMethod.GET, value = "ajaxGetTableDesc")
    @ResponseBody
    public String ajaxGetTableDesc(String tableId) {
        GenTable gentable = genTableService.getById(tableId);
        return null == gentable ? "" : gentable.getComments();
    }

    /**
     * 下载文件
     *
     * @param response
     * @param genFileList
     * @param fileName
     * @throws Exception
     */
    private void downThisFileList(HttpServletResponse response, List<GenFileBean> genFileList, String fileName) throws Exception {
        ZipOutputStream out = null;
        try {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + ".zip");
            out = new ZipOutputStream(response.getOutputStream());
            for (GenFileBean desFile : genFileList) {
                out.putNextEntry(new ZipEntry(desFile.getFileLocation() + File.separator + desFile.getFileName()));
                out.write(desFile.getFileContent().getBytes(Charsets.toCharset("UTF-8")), 0, desFile.getFileContent().getBytes(Charsets.toCharset("UTF-8")).length);
                out.closeEntry();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception("组织下载文件失败！");
        } finally {
            try {
                out.close();
                response.getOutputStream().flush();
                response.getOutputStream().close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

}
